package com.winit.openapi.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sun.misc.BASE64Encoder;

import com.lowagie.text.Document;
import com.lowagie.text.Rectangle;
import com.lowagie.text.RectangleReadOnly;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;

/**
 * 多个PDF合并成一个
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * liang.lu 	1.0  		Mar 16, 2015 	Created
 * 
 * </pre>
 * @since 1.
 */
public class MergePDF {

    public static final Rectangle AX     = new RectangleReadOnly(254F, 254F);
 
    Logger                        logger = LoggerFactory.getLogger(MergePDF.class);

    public static void main(String[] args) {
        MergePDF tool = new MergePDF();
        try {
            List<InputStream> pdfs = new ArrayList<InputStream>();
            String url1 = "http://172.16.2.63/label/2015/03/12/IC2492341450903667CN_999999.PDF";
            String url2 = "http://172.16.2.63/label/2015/03/13/IC2492347850903667CN_999999.PDF";
            pdfs.add(tool.getStreamByUrl(url1));
            pdfs.add(tool.getStreamByUrl(url2));

            String name = "F://src//Winit//2015//03//tmp//tmp.pdf";
            File file = new File(name);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }

            OutputStream output = new FileOutputStream(name);
            tool.merge(pdfs, output);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 合并文件
     * 
     * @param failePath 需要合并的文件列表
     * @param outputFilePath 合并输出文件路径
     */
    public void merge(List<String> failePath, String outputFilePath) {

        List<InputStream> inputStreams = new ArrayList<InputStream>();
        Iterator<String> iteratorPath = failePath.iterator();
        while (iteratorPath.hasNext()) {
            try {
                InputStream inputStream = this.getStreamByUrl(iteratorPath.next());
                if (null != inputStream) {
                    inputStreams.add(inputStream);
                } else {
                    // TODO URL 无效 需要更新错误信息
                }
            } catch (Exception e) {
                logger.error("MergePDF->merge : exception:{}", e.getLocalizedMessage());
            }
        }
        if (inputStreams.size() > 0) {
            try {
                File file = new File(outputFilePath);
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                OutputStream outputStream = new FileOutputStream(outputFilePath);
                this.merge(inputStreams, outputStream);
            } catch (Exception e) {
                logger.error("MergePDF->merge : exception:{}", e.getLocalizedMessage());
            }
        } else {
            logger.warn("MergePDF -> merge :no file to create.");
        }
    }

    /**
     * 合并PDF
     * 
     * @param streamOfPDFFiles
     * @param outputStream
     * @param paginate
     */
    public void merge(List<InputStream> inputStream, OutputStream outputStream) {

        // set print page size & margin of page
        Document document = new Document(AX);
        logger.info("MergePDF -> merge :start merge pdf file.");
        List<InputStream> pdfStreams = inputStream;
        List<PdfReader> pdfReaders = new ArrayList<PdfReader>();

        try {
            Iterator<InputStream> iteratorPDFs = pdfStreams.iterator();
            while (iteratorPDFs.hasNext()) {
                InputStream pdfStream = iteratorPDFs.next();
                PdfReader pdfReader = new PdfReader(pdfStream);
                pdfReaders.add(pdfReader);
            }

            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            PdfImportedPage page;
            int pageOfCurrentReaderPDF = 0;

            Iterator<PdfReader> iteratorPDFReader = pdfReaders.iterator();
            while (iteratorPDFReader.hasNext()) {
                PdfReader pdfReader = iteratorPDFReader.next();
                while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                    document.newPage();
                    pageOfCurrentReaderPDF++;
                    // PDF object start from page 1
                    page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
                    cb.addTemplate(page, 0, 0);
                }
                pageOfCurrentReaderPDF = 0;
            }

            outputStream.flush();
            document.close();
            outputStream.close();
        } catch (Exception e) {
            logger.error("MergePDF -> merge :error:{}", e.getLocalizedMessage());
            e.printStackTrace();
        } finally {

            try {
                if (outputStream != null) {
                    outputStream.close();
                }

            } catch (IOException ioe) {
                ioe.printStackTrace();
            }

            if (document.isOpen()) {
                document.close();
            }
        }
    }

    /**
     * 根据文件的URL获取文件流
     * 
     * @param urlStr
     * @return
     */
    private InputStream getStreamByUrl(String urlStr) {

        URL url = null;
        logger.info("MergePDF->getStreamByUrl url:{}", urlStr);
        try {
            url = new URL(urlStr);
        } catch (MalformedURLException me) {
            me.printStackTrace();
            return null;
        }
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(20 * 1000);
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            return conn.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将文件转成Base64 编码
     * 
     * @param path
     * @return
     */
    public String file2Base64(String path) {
        BASE64Encoder encoder = new BASE64Encoder();
        InputStream inpuSttream = null;
        try {
            inpuSttream = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            logger.info("toBase64:error:{}", e.getLocalizedMessage());
        }
        byte[] byteArray = null;
        try {
            byteArray = IOUtils.toByteArray(inpuSttream);
        } catch (IOException e) {
            logger.info("toBase64:error:{}", e.getLocalizedMessage());
        } finally {
            if (inpuSttream != null) {
                try {
                    inpuSttream.close();
                } catch (IOException e) {
                    logger.info("toBase64:error:{}", e.getLocalizedMessage());
                }
            }
        }
        if (null != byteArray) {
            return encoder.encode(byteArray);
        } else {
            return null;
        }
    }

    /**
     * 删除文件
     * 
     * @param filePath
     * @return
     */
    public Boolean delFile(String filePath) {
        File file = new File(filePath);
        boolean result = false;
        if (file.exists()) {
            result = file.delete();
        }
        return result;
    }

}
